package com.bc.bcapi.utils.web3j;

import com.bc.bccore.web3j.WalletService;
import com.bc.bccore.webconfig.WebConfig;
import org.web3j.utils.Convert;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;

public class Util {

    private static final String ADDRESSPREFIX = "0x";
    private static final String ETHADDRESS = "0xETH";
    private static final String ETHID = "ETH";
    private static final String EOS = "EOS";
    private static final String TRANSFERMETHOD = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
    private static final BigInteger ETHGASLIMIT = new BigInteger("21000");
    private static final BigInteger CONTRACTGASLIMIT = new BigInteger("210000");
    private static final int ETHROUND = 18;
    private static final BigDecimal GASPROMOTION = new BigDecimal(1.2);
    private static final String ISTID = "IST";

    public static BigInteger convertEth2Wei(BigDecimal eth) {
        return Convert.toWei(eth, Convert.Unit.ETHER).toBigInteger();
    }

    public static BigDecimal convertWei2Eth(BigInteger wei) {
        return Convert.fromWei(new BigDecimal(wei), Convert.Unit.ETHER);
    }

    public static String getPrivateKey(String signedPrivateKey, String uid) {
        return WalletService.getInstance().decodePK(signedPrivateKey, uid);
    }

    public static String inAddressFormat(String address) {
        return address.startsWith(ADDRESSPREFIX) ? address.substring(2) : address;
    }

    public static String outAddressFormat(String address) {
        return address.startsWith(ADDRESSPREFIX) ? address : ADDRESSPREFIX + address;
    }

    public static boolean isColdWallet(String wallet) {
        return wallet.equals(WebConfig.getColdWallet());
    }

    public static BigInteger Token2Wei(BigDecimal amount, int digit) {
        for (int i = 0; i < digit; i++) {
            amount = amount.multiply(new BigDecimal(10));
        }
        return amount.toBigInteger();
    }

    public static BigDecimal Wei2Token(BigInteger amount, int digit) {
        BigDecimal rst = new BigDecimal(amount);
        for (int i = 0; i < digit; i++) {
            rst = rst.divide(new BigDecimal(10));
        }
        return rst;
    }

    public static BigDecimal Wei2ETH(BigInteger amount) {
        return Wei2Token(amount, 18);
    }

    public static boolean isContractAddress(String address) throws IOException {
        String code = WalletService.getInstance().getCode(address);
        return !code.equals("0x");
    }

    public static String topic2address(String address) {
        return address.substring(26, address.length());
    }

    public static BigInteger hex2BigInt(String hexValue) {
        if (hexValue.startsWith(ADDRESSPREFIX)) {
            hexValue = hexValue.substring(2);
        }
        return new BigInteger(hexValue, 16);
    }

    public static String getETHADDRESS() {
        return ETHADDRESS;
    }

    public static String getTRANSFERMETHOD() {
        return TRANSFERMETHOD;
    }

    public static String getColdWalletAddress() {
        return WebConfig.getColdWallet();
    }

    public static String getColdWalletPk() {
        String spk = WebConfig.getColdWalletPK();
        String salt = WebConfig.getColdWalletPKSalt();
        return getUserPk(spk, salt);
    }

    public static String getUserPk(String spk, String salt) {
        return WalletService.getInstance().decodePK(spk, salt);
    }

    public static BigInteger estimateGasPrice() throws IOException {
        BigInteger price = WalletService.getInstance().gasPrice();
        BigDecimal gasPriceInETH = Convert.fromWei(price.toString(), Convert.Unit.ETHER);
        return Convert.toWei(gasPriceInETH.multiply(GASPROMOTION).setScale(ETHROUND, BigDecimal.ROUND_UP), Convert.Unit.ETHER).toBigInteger();
    }

    public static BigInteger getETHGASLIMIT() {
        return ETHGASLIMIT;
    }

    public static BigInteger getCONTRACTGASLIMIT() {
        return CONTRACTGASLIMIT;
    }

    public static String getETHID() {
        return ETHID;
    }

    public static String getISTID() {
        return ISTID;
    }

    public static String getEOS() {
        return EOS;
    }

}
